<!-- 拖拽型弹框 -->
<template>
  <el-dialog v-model="show" :show-close="false" :fullscreen="fullscreen" class="common-dialog" :class="getDialogClass"
    :append-to-body="true" :modal-class="getModelClass" ref="dialogDragRef" @mouseDown="mouseDown"
    @mouseMove="mouseMove" @mouseUp="mouseUp" @close="emit('close')" :close-on-press-escape="false"
    :close-on-click-modal="false">
    <template #header>
      <template v-if="props.selfHeader">
        <slot name="selfHeader"></slot>
      </template>
      <template v-else>
        <div class="issue-title">
          <img src="@/assets/img/reserve/title.png" alt="">
          <span>{{ props.dialogTitle }}</span>
        </div>
      </template>
      <div class="dialog-icon" style="display: flex;align-items: center;">
        <el-icon @click="showFullscreen" v-if="!fullscreen && props.isNeedFullscreen" style="margin-right: 10px;color:
          #fff;">
          <FullScreen />
        </el-icon>
        <el-icon @click="closeFullscreen" v-if="fullscreen && props.isNeedFullscreen" style="transform: rotate(180deg);margin-right: 10px;color:
          #fff;">
          <CopyDocument />
        </el-icon>
        <img src="@/assets/img/reserve/close-icon.png" alt="" @click.stop="emit('close')" class="close">
      </div>
    </template>
    <div class="dialog-content scrollBar" :class="props.contentClass" ref="dialogBox"
      :style="{ padding: paddingStyle, height: bodyHeight }">
      <slot name="content"></slot>
    </div>
  </el-dialog>
</template>

<script lang="ts" setup>
import { onMounted, ref, nextTick, computed } from 'vue';
const props = defineProps({
  dialogTitle: { // 弹框标题
    type: String,
    default: ''
  },
  dialogClass: { // 弹框的类名
    type: String,
    default: ''
  },
  contentClass: { // 弹框主体的类名
    type: String,
    default: ''
  },
  isNew: { // 新的弹框的类名
    type: Boolean,
    default: false
  },
  selfHeader: { // 弹框头部插槽
    type: Boolean,
    default: false
  },
  isPadding: { // 弹框主体内边距
    type: String,
  },
  isNeedFullscreen: { // 是否需要全屏
    type: Boolean,
    default: true
  },
  modelClass: { // 遮罩层的class
    type: String,
    default: ''
  }
})

const emit = defineEmits(['close', 'openFull', 'closeFull'])

const show = ref(true) // 弹框展示
const fullscreen = ref(false) // 是否全屏展示
const paddingStyle = computed(() => props.isPadding ? props.isPadding : '15px 15px') // 计算内边距

// 拖拽写法
let dialogDragRef: any = ref(null)
let dragDom: any = ref(null) // 对话框
let dialogHeaderEl: any = ref(null) // 头部
let start = { x: 0, y: 0 } // 模态框距离顶部,左侧距离
let offset = { x: 0, y: 0 } // 模态框偏移距离
let dialogBox = ref<any>(null) // 弹框主体

// 鼠标长按-移动 
const mouseDown = (e: MouseEvent) => {
  // 全屏下不知此长按移动
  if (!props.isNeedFullscreen) return
  document.body.classList.add('user-no-select')
  start.x = e.clientX
  start.y = e.clientY
  const style = window.getComputedStyle(dragDom.value)
  offset.x = parseInt(style.left, 10) - e.clientX
  offset.y = parseInt(style.top, 10) - e.clientY
  document.addEventListener('mousemove', mouseMove)
  document.addEventListener('mouseup', mouseUp)
}

// 鼠标拖曳-移动
const mouseMove = (e: MouseEvent) => {
  // 全屏下不知此长按移动
  if (!props.isNeedFullscreen) return
  document.body.classList.add('user-no-select')
  dragDom.value.style.left = `${e.clientX + offset.x}px`
  dragDom.value.style.top = `${e.clientY + offset.y}px`
}

// 鼠标弹起-移动
const mouseUp = () => {
  // 全屏下不知此长按移动
  if (!props.isNeedFullscreen) return
  document.body.classList.remove('user-no-select')
  document.removeEventListener('mousemove', mouseMove)
  document.removeEventListener('mouseup', mouseUp)
}

onMounted(() => {
  getRectData()
  // 页面监听键盘按下事件
  window.addEventListener('keydown', (e: { key: string }) => {
    // 按下esc 关闭全屏弹窗
    if (e.key === 'Escape') {
      closeFullscreen()
    }
  })
})

// 页面渲染完成后获取弹框元素并监听弹框头部mousedown事件
let bodyHeight = ref('')
const getRectData = () => {
  nextTick(() => {
    const box = dragDom.value = dialogBox.value.parentElement.parentElement // 弹框dom元素
    if (fullscreen.value && props.isNeedFullscreen) {
      bodyHeight.value = dragDom.value.offsetHeight - box.querySelector('.el-dialog__header').offsetHeight - dragDom.value.offsetTop + 'px'// body高度

    } else {
      bodyHeight.value = dragDom.value.offsetHeight - box.querySelector('.el-dialog__header').offsetHeight - 2 * dragDom.value.offsetTop - 60 + 'px'// body高度

    }
    console.log(dragDom.value.offsetHeight,
      box.querySelector('.el-dialog__header').offsetHeight,
      dragDom.value.offsetTop, bodyHeight.value, '高度');

    dialogHeaderEl.value = box.querySelector('.el-dialog__header') as HTMLElement // 弹框头部dom元素
    dialogHeaderEl.value.addEventListener('mousedown', mouseDown) // 绑定鼠标左右键的长按事件
  })
}

// 弹框类名
const getDialogClass = computed(() => {
  let classList = []
  // 定义弹框类名
  if (props.dialogClass) {
    classList.push(props.dialogClass)
  }
  // 新的弹框类名
  if (props.isNew) {
    classList.push('new-dialog')
  }
  return classList
})

// 遮罩层类名
const getModelClass = computed(() => {
  let classList = ['dialog-model']
  if (props.modelClass) {
    console.log(props.modelClass, '遮罩层');

    classList.push(props.modelClass)
  }
  return classList.join(' ')
})

// 打开全屏
const showFullscreen = () => {
  fullscreen.value = true
  dragDom.value.style.left = '0'
  dragDom.value.style.top = '0'
  // 弹框绑定拖曳
  getRectData()
  emit('openFull') // 全屏返回openFull事件

}
// 关闭全屏
const closeFullscreen = () => {
  fullscreen.value = false
  // 弹框绑定拖曳
  getRectData()
  emit('closeFull') // 非全屏返回closeFull事件
}


defineExpose({ dialogBox }) // 弹框主体暴露给父组件
</script>

<style lang="scss">
.common-dialog {
  // width: 100%;
  // height: 100% !important;
  padding: 0 !important;

  .el-dialog__header {
    padding: 15px;
    background: #7d9fe2;
    margin-right: 0px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .dialog-icon {
      >.el-icon {
        width: 30px;
        height: 30px;

        >svg {
          width: 30px;
          height: 30px;
        }
      }

      >img {
        width: 30px;
        height: 30px;
      }
    }

    .issue-title {
      display: flex;
      align-items: center;
      // height: 42%;
      margin-left: 0px;

      >img {
        width: 13px;
        height: 29px;
      }

      span {
        display: inline-block;
        font-family: SourceHanSansCN;
        font-size: 24px;
        margin-left: 13px;
        color: #ffffff;
      }
    }
  }
}

.dialog-content {
  width: 100%;
  // height: 100%;
  overflow: hidden;
}
</style>


<style lang="scss" scoped>
// 不同样式通过文件引入
// .modelClass {
//   background-color: rgba(54, 52, 52, 0.4) !important;
//   // border-radius: 10px;
//   box-shadow: 0 4px 8px rgba(128, 127, 127, 0.8);

// }

// .contentClass {
//   // padding: 15px;
//   // width: 100%;
//   // height: 300px;
//   // background-color: red;
// }</style>